package com.edison.demo.service.impl;

import com.edison.demo.entity.CustomerPersonalBasicInfo;
import com.edison.demo.mapper.CustomerPersonalBasicInfoMapper;
import com.edison.demo.service.BaseDataService;
import com.edison.demo.service.DataService;
import com.edison.demo.until.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.CompletableFuture;

import static com.edison.demo.until.ChineseIDCardNumberGenerator.randomDate;

/**
 * @author edison
 */
@Service
@Slf4j
public class CustomerPersonalBasicInfoServiceImpl implements DataService<CustomerPersonalBasicInfo> {
    private static final Random RANDOM = new Random();

    private final CustomerPersonalBasicInfoMapper customerPersonalBasicInfoMapper;

    @Autowired
    public CustomerPersonalBasicInfoServiceImpl(CustomerPersonalBasicInfoMapper customerPersonalBasicInfoMapper) {
        this.customerPersonalBasicInfoMapper = customerPersonalBasicInfoMapper;
    }

    @Override
    @Async
    public CompletableFuture<List<CustomerPersonalBasicInfo>> initData(int number) {
        log.info("trying to create mock customerPersonalBasicInfo...");
        return BaseDataService.initData(number, this::initCustomerPersonalBasicInfo)
                .thenApply(customerPersonalBasicInfos -> {
                    log.info("Finished creating consumerBaseInfos, number: {}", customerPersonalBasicInfos.size());
                    return customerPersonalBasicInfos;
                });
    }

    @Override
    @Async
    public CompletableFuture<Integer> batchInsert(List<CustomerPersonalBasicInfo> list) {
        return BaseDataService.batchInsert(list,3000,customerPersonalBasicInfoMapper::insert);
    }


    private CustomerPersonalBasicInfo initCustomerPersonalBasicInfo()  {
        String dateFormat = "yyyyMMdd";
        CustomerPersonalBasicInfo customerPersonalBasicInfo = new CustomerPersonalBasicInfo();
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
        String formattedDate = currentDate.format(formatter);
        customerPersonalBasicInfo.setDwEtlDate(formattedDate);

        customerPersonalBasicInfo.setPrticId(PrticIdGenerator.generate());
        customerPersonalBasicInfo.setCustNo(CustomerNumberGenerator.generateCustomerNumber());
        customerPersonalBasicInfo.setCustName(ChineseNameGenerator.generateChineseName());
        customerPersonalBasicInfo.setEnName(EnNameGenerator.generateRandomName());
        customerPersonalBasicInfo.setOpenAcctDt(OpenAcctDtGenerator.generateRandomDateBeforeToday());
        customerPersonalBasicInfo.setOpenAcctOrgNo(OpenAcctOrgNoGenerator.generateOpenAcctOrgNo());
        customerPersonalBasicInfo.setOpenAcctTelrNo(OpenAcctTelrNoGenerator.generateOpenAcctTelrNo());
        String gender = String.valueOf(RANDOM.nextInt(2) + 1);
        customerPersonalBasicInfo.setGender(gender);

        Map<String, String> code = ChineseIDCardNumberGenerator.getAreaCode();
        String areaCode = code.keySet().toArray(new String[0])[RandomUtils
                .nextInt(0, code.size())]
                + StringUtils.leftPad((RandomUtils.nextInt(0, 9998) + 1) + "", 4,
                "0");

        String birthday = new SimpleDateFormat(dateFormat).format(randomDate());
        String randomCode = String.valueOf(1000 + RandomUtils.nextInt(0, 999))
                .substring(1);
        String pre = areaCode + birthday + randomCode;
        String verifyCode = ChineseIDCardNumberGenerator.getVerifyCode(pre);
        String id = pre + verifyCode;

        // Define the date format as "yyyyMMdd"
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
        try {
            Date birthDt = simpleDateFormat.parse(birthday);
            customerPersonalBasicInfo.setBirthDt(birthDt);
        } catch (ParseException e) {
            log.error(e.getMessage());
        }

        // hard code for docType, all value from data example seem like same as "110000"
        customerPersonalBasicInfo.setDocType("110000");
        customerPersonalBasicInfo.setDocNumber(id);
        customerPersonalBasicInfo.setDocBeginDt(OpenAcctDtGenerator.generateRandomDateStringBeforeToday());
        customerPersonalBasicInfo.setDocMatrDt(OpenAcctDtGenerator.generateFutureDate());
        customerPersonalBasicInfo.setLicAuthName(ChineseIDCardNumberGenerator.generateIssueOrg());
        customerPersonalBasicInfo.setLicAuthCtryRgnCd("CHN");
        customerPersonalBasicInfo.setOrganizationId(areaCode);
        customerPersonalBasicInfo.setStatusCode( String.valueOf(RANDOM.nextInt(2) + 1));
        customerPersonalBasicInfo.setIdCardNtwrkVfconReslt(String.valueOf(RANDOM.nextInt(2)));
        customerPersonalBasicInfo.setCitizenIdentyUnableVrfyRsn(null);
        customerPersonalBasicInfo.setAfltOrgNo(AfltOrgNoGenerator.generateAfltOrgNo());
        customerPersonalBasicInfo.setNtnty("CHN");
        customerPersonalBasicInfo.setAfltCustMngrNo(CustomerManagerNumberGenerator.generateCustomerManagerNumber());

        customerPersonalBasicInfo.setNtvPlac(ChineseAddressGenerator.generate());

        String provinceAndCity = ChineseAddressGenerator.genProvinceAndCity();
        String detailAddress = ChineseAddressGenerator.generateDetailAddress();

        customerPersonalBasicInfo.setNtvPlac(provinceAndCity);
        customerPersonalBasicInfo.setPsnAnlIncm(1000);
        customerPersonalBasicInfo.setUnitName(ChineseCompanyNameGenerator.generateCompanyName());
        customerPersonalBasicInfo.setUnitAddr(provinceAndCity + detailAddress);
        customerPersonalBasicInfo.setUnitTelNo(ChineseMobileNumberGenerator.generate());
        customerPersonalBasicInfo.setCommnRsialAddr(ChineseAddressGenerator.generateDetailAddress());
        customerPersonalBasicInfo.setRegisteredAddress(ChineseAddressGenerator.generateDetailAddress());
        customerPersonalBasicInfo.setRsialTel(ChineseMobileNumberGenerator.generate());
        customerPersonalBasicInfo.setPhoneNo(ChineseMobileNumberGenerator.generate());
        customerPersonalBasicInfo.setCommnRsialAddr(ChineseAddressGenerator.generate());


        return customerPersonalBasicInfo;

    }
}
